package com.workcell.workdata.xthings.service.impl.mqtt;


import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.workcell.workdata.xthings.entity.mqtt.WaterMeterData;
import com.workcell.workdata.xthings.mapper.WaterMeterDataMapper;
import com.workcell.workdata.xthings.service.WaterMeterDataService;
import com.workcell.workdata.xthings.utils.DateTimeUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.ListIterator;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 阀门
 */
@RequiredArgsConstructor
@Service
@DS("slave_mqtt")
public class WaterMeterDataServiceImpl extends ServiceImpl<WaterMeterDataMapper, WaterMeterData> implements WaterMeterDataService {

    private final RedisTemplate redisTemplate;

    private final String baseCodeBaseRedisKey = "DataQrCode_WaterMeter_DataHourLineChartInfo_%s_%s";

    private final SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");

    /**
     * 获取硬件最近六个小时的数据：折线图
     * @param deviceNo
     * @return
     */
    public Object getDataHourLineChartInfo(String deviceNo, String manufacturerCode) {
        Map<String, WaterMeterData> waterMeterDataMap = new LinkedHashMap<>(6);
        // 获取当前小时时间
        Date nowHourTime = DateTimeUtil.addHourAndFormatSM(0);
        Date nowHourTimeAddOne = DateTimeUtil.addHourAndFormatSM(-1);
        checkRedisSearchDbDataChar(waterMeterDataMap, deviceNo, manufacturerCode, nowHourTimeAddOne, nowHourTime);
        // 处理一个小时前的数据
        Date nowHourTimeSub1 = DateTimeUtil.addHourAndFormatSM(-2);
        checkRedisSearchDbDataChar(waterMeterDataMap, deviceNo, manufacturerCode, nowHourTimeSub1, nowHourTimeAddOne);
        // 处理两个小时前的数据
        Date nowHourTimeSub2 = DateTimeUtil.addHourAndFormatSM(-3);
        checkRedisSearchDbDataChar(waterMeterDataMap, deviceNo, manufacturerCode, nowHourTimeSub2, nowHourTimeSub1);
        // 处理三个小时前的数据
        Date nowHourTimeSub3 = DateTimeUtil.addHourAndFormatSM(-4);
        checkRedisSearchDbDataChar(waterMeterDataMap, deviceNo, manufacturerCode, nowHourTimeSub3, nowHourTimeSub2);
        // 处理四个小时前的数据
        Date nowHourTimeSub4 = DateTimeUtil.addHourAndFormatSM(-5);
        checkRedisSearchDbDataChar(waterMeterDataMap, deviceNo, manufacturerCode, nowHourTimeSub4, nowHourTimeSub3);
        // 处理五个小时前的数据
        Date nowHourTimeSub5 = DateTimeUtil.addHourAndFormatSM(-6);
        checkRedisSearchDbDataChar(waterMeterDataMap, deviceNo, manufacturerCode, nowHourTimeSub5, nowHourTimeSub4);

        // 组装数据
        JSONArray typeArray = new JSONArray();
        typeArray.add("用水量");
        JSONArray timeArray = new JSONArray();

        JSONArray informationArray = new JSONArray();

        JSONObject deviceStatusObj = new JSONObject();
        deviceStatusObj.put("name","用水量");
        JSONArray deviceStatusArray = new JSONArray();
        // 逆序遍历
        ListIterator<Map.Entry<String, WaterMeterData>> i =
                new ArrayList<>(waterMeterDataMap.entrySet()).listIterator(waterMeterDataMap.size());
        while(i.hasPrevious()) {
            Map.Entry<String, WaterMeterData> entry = i.previous();
            timeArray.add(entry.getKey());
            deviceStatusArray.add(entry.getValue().getCumulativeWaterVolumeDiffDataHour());
        }
        deviceStatusObj.put("data",deviceStatusArray);
        informationArray.add(deviceStatusObj);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("typeArray",typeArray);
        jsonObject.put("timeArray",timeArray);
        jsonObject.put("informationArray",informationArray);
        return jsonObject;
    }

    /**
     * 判断redis存在当前时间段的缓存，否则查询库存储
     * @param deviceNo 设备编号
     * @param nowHourTime 开始时间
     * @param nowHourTimeAddOne 结束时间
     */
    public void checkRedisSearchDbDataChar(Map<String, WaterMeterData> waterMeterDataMap, String deviceNo, String manufacturerCode, Date nowHourTime, Date nowHourTimeAddOne){
        Object nowHourTimeDate = redisTemplate.opsForValue().get(String.format(baseCodeBaseRedisKey,deviceNo,nowHourTime));
        if (ObjectUtil.isEmpty(nowHourTimeDate)){
            nowHourTimeDate = this.baseMapper.getDataHourLineChartInfo(deviceNo, manufacturerCode, nowHourTime, nowHourTimeAddOne);
            if (ObjectUtil.isNotEmpty(nowHourTimeDate)){
                redisTemplate.opsForValue().set(String.format(baseCodeBaseRedisKey,deviceNo,nowHourTime),nowHourTimeDate,1, TimeUnit.DAYS);
            }
        }
        waterMeterDataMap.put(sdf.format(nowHourTime),ObjectUtil.isEmpty(nowHourTimeDate)?new WaterMeterData():(WaterMeterData) nowHourTimeDate);
    }


    public Object getLatelyDataInfo(String deviceNo, String manufacturerCode, Integer time) {
        return baseMapper.getLatelyDataInfo(deviceNo,manufacturerCode,time);
    }
}
